#pragma once

#include "core/tensor.h"

namespace  ldl
{
namespace layer
{
template<typename T>
class Hidden
{
public:
    virtual ~Hidden() = default;

    /**
     * @brief 前向传播
     */
    virtual Core::Tensor& forward(const Core::Tensor &input) = 0;

    /**
     * @brief 反向传播
     */
    virtual Core::Tensor& backward(const Core::Tensor &output_gradient) = 0;

    /**
     * @brief 获取输出数据
     */
    virtual Core::Tensor& output() final
    {
        return m_output;
    }

    /**
     * @brief 获取损失对输入的偏导
     */
    virtual Core::Tensor& input_gradient() final
    {
        return m_input_gradient;
    }

protected:
    /**
     * @brief 输入数据，该数据由外部持有，当前层仅有一个数据的一个视图
     */
    Core::TensorView m_input{};

    /**
     * @brief 输出数据，该数据由本层持有
     */
    Core::Tensor m_output{};

    /**
     * @brief 损失对输入的偏导，该数据由本层持有
     */
    Eigen::MatrixXf m_input_gradient{};
};
}
}
